package eval

import (
	"embed"
	"io/fs"
	"testing"
)

func AddBaseFuzzCases(f *testing.F) {
	f.Add("5")
	f.Add(`"hello"`)
	f.Add(`{}`)
	f.Add(`[]`)
	f.Add(`[5 "hello"]`)
	f.Add(`{ key = 5; }`)
	f.Add(`let a = 10; in a * 2`)
	f.Add(`(n: n * 2) 21`)
}

func FuzzSimpleLazyEval(f *testing.F) {
	AddBaseFuzzCases(f)

	f.Fuzz(func(t *testing.T, code string) {
		_, _ = EvalNix(code, false)
	})
}

func FuzzSimpleStrictEval(f *testing.F) {
	AddBaseFuzzCases(f)

	f.Fuzz(func(t *testing.T, code string) {
		_, _ = EvalNix(code, true)
	})
}

// Fuzz corpus based on tests that are expected to work.

//go:embed cmd/evaltests/testdata
var testdata embed.FS

func FuzzEvalOkayLazy(f *testing.F) {
	tests, err := fs.Glob(testdata, "cmd/evaltests/testdata/*_tests/eval-okay-*.nix")
	if err != nil || len(tests) == 0 {
		f.Fatal("failed to list eval-okay tests:", err)
	}

	for _, test := range tests {
		test, err := fs.ReadFile(testdata, test)
		if err != nil {
			f.Fatalf("failed to read input from %s: %s", test, err)
		}

		f.Add(string(test))
	}

	f.Fuzz(func(t *testing.T, code string) {
		_, _ = EvalNix(code, false)
	})
}
